/*
 * This file is part of the Try! Engine project.
 *
 * Copyright 2010-2011 Emanuele Bertoldi. All rights reserved.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * You should have received a copy of the modified BSD License along with this
 * program. If not, see <http://www.opensource.org/licenses/bsd-license.php>
 */

#include "physicsmanager.h"

using namespace Try;

PhysicsManager::PhysicsManager(
    bool with_softbody,
    const btVector3& gravity
    )
    :   m_broadphase(0),
        m_collisionConfiguration(0),
        m_dispatcher(0),
        m_solver(0),
        m_world(0)
{
    // Build the broadphase.
    m_broadphase = new btDbvtBroadphase();

    // Set up the collision configuration and dispatcher.
    m_collisionConfiguration = new btDefaultCollisionConfiguration();
    m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);

    // The actual physics solver.
    m_solver = new btSequentialImpulseConstraintSolver();

    if (with_softbody)
        m_world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
    else
        m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);

    m_world->setGravity(gravity);
}

PhysicsManager::~PhysicsManager()
{
    delete m_world;
    m_world = 0;

    delete m_solver;
    m_solver = 0;

    delete m_dispatcher;
    m_dispatcher = 0;

    delete m_collisionConfiguration;
    m_collisionConfiguration = 0;

    delete m_broadphase;
    m_broadphase = 0;
}

btDiscreteDynamicsWorld* PhysicsManager::internal() const
{
    return m_world;
}

void PhysicsManager::simulateOneStep(float dt)
{
    m_world->stepSimulation(dt);
}
